Návrh komponent · Record detail · ACRM Design System

Sjednocení tabů napříč detaily záznamů

Osoba, firma, obchod i schůzka dnes vykreslují stejné taby — úkoly, e-maily, poznámky, produkty — každý po svém, ve třech CSS namespacech a s odchýleným obsahem. Návrh zavádí jeden datově řízený tab host a knihovnu kanonických panelů po vzoru už existujícího Record detail rail: obsah tabu je identický všude, kód žije na jednom místě.

18
unikátních tabů rozesetých mezi 4 typy detailů — reálně jde o 9 vzorů.
3×
„Úkoly" existují ve třech různých implementacích. „E-maily" ve dvou.
2
paralelní CSS namespacy tabů (.pr- a .mr-) — zdroj driftu.
01Inventář — přehled o všech tabech

Kompletní mapa tabů × typů záznamu

Řádky = každý tab, který se v produktu objevuje. Sloupce = čtyři typy detailu. Barva buňky říká, do které vrstvy tab patří — a tím i to, jak se má sjednotit. Značka drift označuje místa, kde se dnešní implementace liší i tam, kde by měla být totožná.

Univerzální — identický panel všude Vazba — jeden panel, parametr = typ relace Specifický — jen pro daný typ Není v tomto typu
Tab9 kanonických vzorů
Osoba
Firma
Obchod
Schůzka
Vrstva A — univerzálnístejný panel, jen jiná data · žádné odchylky
Přehledskládaný souhrn — highlight karty + mini bloky
–
Aktivitajednotná časová osa událostí
–
E-mailydrift bohatý výpis vs. prázdný SimpleTab
–
Poznámkyna schůzce jako „Vlastní zápis" — tentýž editor
Vlastní zápis
Úkolydrift ×3 TaskList · SimpleTab · vlastní .task-grp
návrhy AI
Souborypřílohy a dokumenty
–
–
Vrstva B — vazbyjeden RelationsPanel, řízený typem navázané entity
Schůzky3 názvy „Setkání" (hovory / setkani) vs. „Schůzky"
Setkání
Setkání
–
Lidé / Kontaktynavázané osoby — na osobě jako „Firmy"
Firmy
Lidé
Kontakty
Účastníci
Obchody / Projektynavázané dealy nebo projekty
Projekty
Obchody
Provázání / Seznamyobecné vazby a členství v seznamech
Provázání
–
Vrstva C — specifickéjedinečné pro typ · vlastní panel, ale sdílené stavební prvky
Produktypoložky a částky obchodu
–
–
–
Historie fázíaudit posunů pipeline
–
–
–
Souhrn · PřepisAI shrnutí a přepis hovoru
–
–
–
02Diagnóza — proč to teď drhne

Stejný tab, tři pravdy

Taby se kopírovaly z obrazovky na obrazovku a pak se každá vyvíjela zvlášť. Výsledek: uživatel vidí „Úkoly" na osobě jinak než na obchodu, a designér musí opravit chybu na čtyřech místech.

„Úkoly" ve třech provedeních

Osoba a firma volají sdílený DS.TaskList. Obchod ukazuje prázdný SimpleTab. Schůzka má vlastní .task-grp se skupinami „Navrhované / Schválené". Tři různé řádky, checkboxy i chování.

DS.TaskListSimpleTab.task-grp
Jeden koncept, tři názvy

Navázané schůzky se jmenují Setkání (klíč hovory) na osobě, Setkání (klíč setkani) na firmě a Schůzky na obchodu. Rozdílné popisky i klíče stavu = nekonzistence a křehké odkazy.

Setkání / hovorySetkání / setkaniSchůzky / schuzky
Dva CSS namespacy

Osoba, firma i obchod používají .pr-tabs; schůzka celý vlastní .mr-tabs. Dvě sady stylů pro tentýž underline strip — každá oprava se musí dělat dvakrát a stejně se rozjedou.

.pr-tabs.mr-tabs.acrm-tabs ✓
Prázdné stavy à la carte

Prázdný tab má na obchodu bohatý EmptyState s CTA, jinde tichý text nebo nic. Prázdno je přitom nejčastější stav — patří do panelu, ne do každé obrazovky zvlášť.

DS.EmptyState ✓tichý text— nic —
03Návrh — jeden host, knihovna panelů

Datově řízený <RecordTabs> — dvojče Record detail railu

Rail už tenhle vzor dokázal: jedna komponenta řízená konfigurací obsluhuje firmu, osobu, obchod i schůzku — přepínač mění jen data, ne kód. Taby dostanou totéž. Obrazovka jen řekne které taby a z jakého datového řezu; host + panel se postarají o vzhled a stavy.

Konfigurace obrazovky — jediné, co detail píše
// Obchod detail — jen výběr tabů + data const tabs = [ { key: "prehled", panel: Overview }, { key: "produkty", panel: Products, count: 2 }, { key: "ukoly", panel: Tasks }, { key: "emaily", panel: Emails }, { key: "poznamky", panel: Notes, count: 1 }, { key: "schuzky", panel: Relations, rel: "meeting" }, ]; <RecordTabs record={deal} tabs={tabs} />
Co dělá host — společné pro všechny detaily
// RecordTabs — jednou, sdíleně • vykreslí .acrm-tabs strip (ikona · label · count pill · aktivní podtržení) • přetečení → edge-fade + šipky, posun 60 % • aktivní tab v URL (deep-link, zpět/vpřed) • lazy-mount panelu, drží scroll pozici • loading / empty / error obalí každý panel • kanonický registr klíčů → žádné „hovory" vs „setkani"
RecordTabs (host)
strip · nav · stavy · registr klíčů
Panel (čistý)
dostane datový řez, vykreslí obsah — nic neví o typu detailu
DS prvky
TaskList · EmailList · EmptyState · entity chip · pill
04Knihovna kanonických panelů

Devět panelů, každý s jedním zdrojem pravdy

Každý panel je čistá komponenta: dostane normalizovaný datový řez a vykreslí ho — včetně prázdného, načítacího a chybového stavu. Detail nikdy nesahá do vnitřku panelu, jen dodá data.

Tasks
TasksPanel · key: ukoly
univerzální
SjednocujeTaskList na osobě/firmě, prázdný obchod, .task-grp schůzky → jeden panel
Staví naDS.TaskList hairline řádky, kulatý checkbox, termín, řešitel
Parametrygroups (otevřené / hotové / návrhy AI), onAdd
Emails
EmailsPanel · key: emaily
univerzální
Sjednocujebohatý .eml-list (osoba/firma) i prázdný obchod → stejný výpis
Řádekavatar · předmět + souhrn · přes koho + datum · kategorie pill
Parametrythreads, scope (osoba × firma × obchod)
Notes
NotesPanel · key: poznamky
univerzální
Sjednocujepoznámky detailů + „Vlastní zápis" schůzky → tentýž editor
Chováníinline autosave (vzor railu), „Uloženo" potvrzení, autor + čas
Parametrynotes, title (alias „Vlastní zápis")
Files · Overview · Activity
FilesPanel · OverviewPanel · ActivityPanel
univerzální
Filesedge-to-edge výpis příloh, drop zóna, prázdný stav
Overviewskládá highlight karty + mini bloky — slot-based, obsah dodá typ
Activityjedna časová osa (e-mail · hovor · úkol · změna pole)
Relations
RelationsPanel · 1 panel, N vazeb
vazba
PokrýváSchůzky · Lidé/Kontakty/Účastníci · Obchody/Projekty · Provázání
Klíčrel="meeting|person|deal|company|list" → entity chip + meta + prázdno
Řešídrift názvů — kanonický popisek podle rel, ne per-obrazovka
Products · Stage history · Meeting AI
specifické panely
specifické
Productstabulka položek + částky (obchod) — na DataTable
Stage historyaudit fází pipeline (obchod)
Souhrn/PřepisAI shrnutí a přepis (schůzka) — vlastní, ale sdílí prvky
05Způsob práce — jak to zavést bez velkého třesku

Postupná migrace, panel po panelu

Nepřepisovat čtyři obrazovky najednou. Nejdřív povýšit strip a nejrozbitější panel, pak přepínat obrazovky jednu po druhé na host. Každý krok je samostatně nasaditelný.

01
Kanonizovat strip
Povýšit .acrm-tabs (už existuje jako karta) na host RecordTabs — nav, overflow, deep-link, count pill. Zrušit .pr-tabs i .mr-tabs.
základ hotov
02
Extrahovat 3 univerzální panely
Tasks, Emails, Notes — sjednotit tři/dvě implementace do jedné komponenty se stavy. Největší úbytek driftu za nejmíň práce.
1 sprint
03
Postavit RelationsPanel
Jeden panel řízený rel. Zavést kanonický registr klíčů/popisků — konec „hovory vs. setkani vs. schuzky".
1 sprint
04
Přepnout obrazovky na host
Osoba → firma → obchod → schůzka. Každý detail redukovat na konfiguraci tabů + specifické panely. Screeny zůstanou vizuálně stejné, kód spadne o desítky procent.
2 sprinty
05
Uklidit a zamknout
Smazat mrtvé .pr-/.mr- styly, přidat panely jako karty do skupiny Components, doplnit lint pravidlo proti novým namespacům tabů.
0,5 sprintu

Pravidla, aby drift nevznikl znovu

1Klíč tabu je kanonický. Množina povolených klíčů žije v registru (prehled · aktivita · emaily · poznamky · ukoly · soubory · relations · produkty …). Obrazovka klíč vybírá, nevymýšlí.
2Popisek patří ke klíči, ne k obrazovce. „Setkání" i „Schůzky" jsou jeden klíč relations rel=meeting; alias popisku se řeší v hostu, ne copy-paste na screenu.
3Panel neví, na jakém detailu běží. Dostane datový řez a hotovo. Žádné if (type === "deal") uvnitř panelu — jinak se drift vrátí zadními vrátky.
4Stavy vlastní host. Loading, empty i error obaluje RecordTabs jednotně (DS.EmptyState / skeleton). Prázdno není věc obrazovky.
5Nová komponenta = karta ve skupině Components. Panel bez karty v DS neexistuje — sjednocení se udrží jen když je viditelné.
Otevřené otázky — než začnu stavět
  • Pořadí tabů — má být fixní kanonické pořadí napříč typy (predikovatelnost), nebo si ho každý typ řadí sám podle důležitosti?
  • Přehled na schůzce — schůzka dnes Přehled/Aktivitu jako tab nemá (má je v levém railu). Sjednotit ji taky pod RecordTabs, nebo ji nechat jako výjimku?
  • Setkání vs. Schůzky — který popisek je kanonický? Návrh: Schůzky (věcné, sentence case), „Setkání" zrušit.
  • Rozsah teď — mám rovnou postavit živé RecordTabs + 3 univerzální panely jako komponenty do skupiny Components, nebo nejdřív odsouhlasit tuhle mapu?